import fs from 'node:fs';
import path from 'node:path';
import http from 'node:http';
import https from 'node:https';
import { FakeApi, random } from '@wowon/utils';
import { getCurrentUser } from '../../auth-center';

let folderDeep = 0;
let folderIds = [];
const initFolder = [
  {
    deep: 0,
    id: `__$folder_user_avatar`,
    pid: '_root',
    name: '用户头像',
    count: 0,
    remark: '用户头像',
  },
  {
    deep: 0,
    id: `__$folder_cover`,
    pid: '_root',
    name: '封面',
    count: 0,
    remark: '用户封面、公告封面等',
  },
].concat(
  Array.from({ length: random(15, 30) }).map((_, i) => {
    let id = `i-0${i}`;
    const deep = folderDeep;

    if (!folderIds[deep]) folderIds[deep] = [];
    folderIds[deep].push(id);
    folderDeep = Math.min(folderIds[deep].length > (deep + 1) * 3 ? folderDeep + 1 : folderDeep, 2);

    return {
      deep,
      id: i === 0 ? '__$folder_default' : id,
      pid: deep === 0 ? '_root' : random(folderIds[deep - 1]),
      name: i === 0 ? '.default' : `folder-${i}`,
      count: 10,
      remark: `文件夹-${i}`,
    };
  }),
);

const folderList = new FakeApi(initFolder, {
  queryType: {
    pid: 'is',
  },
});

const initFiles = Array.from({ length: 400 }).map((_, i) => {
  return {
    id: `__$file_${i}`,
    pid: i < 200 ? '__$folder_cover' : '__$folder_user_avatar',
    name: i < 200 ? `test-cover-${i}.png` : `test-avatar-${i - 200}.png`,
    extname: 'png',
    url:
      i < 200
        ? `https://picsum.photos/seed/${i}/400`
        : `https://api.dicebear.com/8.x/micah/svg?seed=${i}&baseColor=f9c9b6&backgroundColor=b6e3f4,c0aede,d1d4f9&hair=dannyPhantom,fonze,full,pixie`,
    size: random(1000, 9999999),
    mime: 'image/png',
    type: 'image',
    remark: '',
  };
});

export const fileList = new FakeApi(initFiles, {
  queryType: {
    pid: 'is',
    id: 'is',
    name: 'like',
    type: 'is',
  },
});

const extensionToMime = {
  '.jpg': 'image/jpeg',
  '.jpeg': 'image/jpeg',
  '.png': 'image/png',
  '.gif': 'image/gif',
  '.bmp': 'image/bmp',
  '.webp': 'image/webp',
};

export default {
  // ---------------- 文件夹操作 ----------------
  'GET /mock/folder/list': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await folderList.list(req.query);
    res.json(result);
  },
  'POST /mock/folder/create': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await folderList.create(req.body);
    res.json(result);
  },
  'POST /mock/folder/update': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await folderList.update(req.body);
    res.json(result);
  },
  'POST /mock/folder/remove': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await folderList.remove(req.body);
    res.json(result);
  },
  // ---------------- 文件操作 ----------------
  'GET /mock/file/query': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await fileList.query(req.query);
    res.json({ ...result, list: fileList._list });
  },
  'POST /mock/file/upload': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const file = req.files?.[0];
    if (!file) {
      res.json({ code: -1, message: '请选择文件上传！' });
      return;
    }
    const fileKey = new Date().toLocaleString().replace(/\/|\s|:/g, '') + '-' + random(1000, 9999);
    const fileName = file.originalname.replace(/(.+)\.(.+)/, '$1-' + fileKey + '.$2');
    const uploadPath = path.join(__dirname, `../../public/upload/${fileName}`);
    try {
      fs.writeFileSync(uploadPath, file.buffer);
    } catch (err) {
      res.json({ code: -2, message: '文件保存失败！' });
      return;
    }
    const fileData = {
      id: `file-${fileKey}`,
      pid: req.body.pid || '_root',
      name: req.body.name || file.originalname,
      extname: file.originalname.replace(/.+\./, ''),
      url: uploadPath.replace(/.+public/, ''),
      size: file.size,
      mime: file.mimetype,
      type: file.mimetype.replace(/\/.+/, ''),
      remark: req.body.remark || '',
    };
    const result = await fileList.create(fileData);
    res.json({ ...result, data: fileData });
  },
  'POST /mock/file/extract': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const { pid, url, remark } = req.body;

    let extname = path.extname(url).toLowerCase();

    const fileKey = new Date().toLocaleString().replace(/\/|\s|:/g, '') + '-' + random(1000, 9999);
    const fileName = !extname ? fileKey : path.basename(url.replace(/\?.+/, '')).replace(/(.+)\.(.+)/, '$1-' + fileKey);
    const protocol = url.startsWith('https') ? https : http;

    protocol
      .get(url, (response) => {
        if (response.statusCode !== 200) {
          res.json({ code: -2, message: '文件获取失败！' });
        }

        let mime = response.headers['content-type'];
        if (!mime) {
          // 如果响应头中没有 MIME 类型，根据文件扩展名推断
          mime = extensionToMime[extname] || 'application/octet-stream';
        } else if (!extname) {
          extname = mime.replace(/.+\//, '');
        }
        const uploadPath = path.join(__dirname, `../../public/upload/${fileName}.${extname}`);

        // 创建可写流以保存图片
        const fileStream = fs.createWriteStream(uploadPath);
        response.pipe(fileStream);

        // 监听流的结束事件
        fileStream.on('finish', async () => {
          fileStream.close();
          try {
            // 获取图片的基本信息
            const stats = fs.statSync(uploadPath);

            const fileData = {
              id: `file-${fileKey}`,
              pid: pid || '_root',
              name: fileName,
              extname: extname,
              url: uploadPath.replace(/.+public/, ''),
              size: stats.size,
              mime: mime,
              type: mime.replace(/\/.+/, ''),
              remark: remark || '',
            };
            const result = await fileList.create(fileData);
            res.json({ ...result, data: fileData });
          } catch (err) {
            try {
              fs.unlinkSync(uploadPath);
            } catch (error) {}
            res.json({ code: -3, message: '文件获取信息失败！' });
          }
        });

        // 监听流的错误事件
        fileStream.on('error', () => {
          try {
            fs.unlinkSync(uploadPath);
          } catch (error) {}
          res.json({ code: -4, message: '文件保存失败！' });
        });
      })
      .on('error', () => {
        res.json({ code: -1, message: '文件获取失败！' });
      });
  },
  'POST /mock/file/update': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await fileList.update(req.body);
    res.json(result);
  },
  'POST /mock/file/remove': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await fileList.remove(req.body);
    res.json(result);
  },
  'GET /mock/file/list': async (req, res) => {
    const currentUser = getCurrentUser(req);
    if (!currentUser) {
      res.statusCode = 401;
      res.json({ code: '-1', message: '权限不足' });
      return;
    }
    const result = await fileList.list(req.query);
    res.json(result);
  },
};
